home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / pro_line.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  8.2 KB  |  262 lines

  1. /*
  2.     pro_line.c
  3.     $Revision: 1.8 $    $Date: 1994/06/02 17:40:20 $    
  4.     $Source: /cmplrs.src/v4.00/libdwarf/RCS/pro_line.c,v $
  5.  
  6.     Contains routines for adding line number information.
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <elf.h>
  12. #include "pro_incl.h"
  13. #include "pro_line.h"
  14.  
  15. Dwarf_Unsigned _dwarf_pro_add_line_entry(Dwarf_P_Debug,Dwarf_Unsigned file_index,Dwarf_Addr code_address,Dwarf_Unsigned symidx,Dwarf_Unsigned line_no, Dwarf_Signed col_no, Dwarf_Bool is_stmt_begin, Dwarf_Bool is_bb_begin, Dwarf_Ubyte opc, Dwarf_Error *error);
  16.  
  17. /*-------------------------------------------------------------------------
  18.     Add a entry to the line information section
  19.     file_index: index of file in file entries, obtained from
  20.     add_file_entry() call. 
  21.     
  22.     This function actually calls _dwarf_pro_add_line_entry(), with
  23.     an extra parameter, the opcode. Done so that interface calls
  24.     dwarf_lne_set_address() and dwarf_lne_end_sequence() can use
  25.     this internal routine.
  26. ---------------------------------------------------------------------------*/
  27. Dwarf_Unsigned
  28. dwarf_add_line_entry(
  29.     Dwarf_P_Debug dbg,
  30.     Dwarf_Unsigned file_index,
  31.     Dwarf_Addr code_address,
  32.     Dwarf_Unsigned line_no,
  33.     Dwarf_Signed col_no,
  34.     Dwarf_Bool is_stmt_begin,
  35.     Dwarf_Bool is_bb_begin,
  36.     Dwarf_Error *error)
  37. {
  38.     Dwarf_Unsigned retval;
  39.  
  40.     retval = _dwarf_pro_add_line_entry(dbg,file_index,code_address,0,
  41.         line_no,col_no,is_stmt_begin,is_bb_begin,0,error);
  42.     return retval;
  43. }
  44.  
  45. /*------------------------------------------------------------------------
  46.     Ask to emit DW_LNE_set_address opcode explicitly. Used by be
  47.     to emit start of a new .text section, or to force a relocated
  48.     address into debug line information entry.
  49. -------------------------------------------------------------------------*/
  50. Dwarf_Unsigned 
  51. dwarf_lne_set_address(
  52.     Dwarf_P_Debug dbg, 
  53.     Dwarf_Addr offs,
  54.     Dwarf_Unsigned symidx,
  55.     Dwarf_Error *error)
  56. {
  57.     Dwarf_Ubyte opc;
  58.     Dwarf_Unsigned retval;
  59.  
  60.     opc = DW_LNE_set_address;
  61.     retval = _dwarf_pro_add_line_entry(dbg,0,offs,symidx,0,0,0,0,opc,error);
  62.     return retval;
  63. }
  64.  
  65. /*------------------------------------------------------------------------
  66.     Ask to emit end_seqence opcode. Used normally at the end of a 
  67.     compilation unit. Can also be used in the middle if there
  68.     are gaps in the region described by the code address. 
  69. -------------------------------------------------------------------------*/
  70. Dwarf_Unsigned 
  71. dwarf_lne_end_sequence(
  72.     Dwarf_P_Debug dbg, 
  73.     Dwarf_Addr end_address,
  74.     Dwarf_Error *error)
  75. {
  76.     Dwarf_Ubyte opc;
  77.     Dwarf_Unsigned retval;
  78.  
  79.     opc = DW_LNE_end_sequence;
  80.     retval = 
  81.         _dwarf_pro_add_line_entry(dbg,0,end_address,0,0,0,0,0,opc,error);
  82.     return retval;
  83. }
  84.  
  85. /*----------------------------------------------------------------------------
  86.     Add an entry in the internal list of lines mantained by producer. 
  87.     Opc indicates if an opcode needs to be generated, rather than just
  88.     an entry in the matrix. During opcodes generation time, these 
  89.     opcodes will be used.
  90. -----------------------------------------------------------------------------*/
  91. Dwarf_Unsigned
  92. _dwarf_pro_add_line_entry(
  93.     Dwarf_P_Debug dbg,
  94.     Dwarf_Unsigned file_index,
  95.     Dwarf_Addr code_address,
  96.     Dwarf_Unsigned symidx,
  97.     Dwarf_Unsigned line_no,
  98.     Dwarf_Signed col_no,
  99.     Dwarf_Bool is_stmt_begin,
  100.     Dwarf_Bool is_bb_begin,
  101.     Dwarf_Ubyte opc,
  102.     Dwarf_Error *error)
  103. {
  104.     if (dbg->de_lines == NULL) {    
  105.         dbg->de_lines = (Dwarf_P_Line) 
  106.             _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
  107.         if (dbg->de_lines == NULL) {
  108.             DWARF_P_DBG_ERROR(dbg,DW_DLE_LINE_ALLOC,DW_DLV_NOCOUNT);
  109.         }
  110.         dbg->de_last_line = dbg->de_lines;
  111.         _dwarf_pro_reg_init(dbg->de_lines);
  112.  
  113.     } else { 
  114.         dbg->de_last_line->dpl_next = (Dwarf_P_Line) 
  115.             _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
  116.         if (dbg->de_last_line->dpl_next == NULL) {
  117.             DWARF_P_DBG_ERROR(dbg,DW_DLE_LINE_ALLOC,DW_DLV_NOCOUNT);
  118.         }
  119.         dbg->de_last_line = dbg->de_last_line->dpl_next;
  120.         _dwarf_pro_reg_init(dbg->de_last_line);
  121.     }
  122.     dbg->de_last_line->dpl_address = code_address;
  123.     dbg->de_last_line->dpl_file = file_index;
  124.     dbg->de_last_line->dpl_line = line_no;
  125.     dbg->de_last_line->dpl_column = col_no;
  126.     dbg->de_last_line->dpl_is_stmt = is_stmt_begin;
  127.     dbg->de_last_line->dpl_basic_block = is_bb_begin;
  128.     dbg->de_last_line->dpl_opc = opc;
  129.     dbg->de_last_line->dpl_r_symidx = symidx;
  130.  
  131.     return(0);
  132. }
  133.  
  134. /*-----------------------------------------------------------------------
  135.     Add a directory declaration to the debug_line section. Stored
  136.     in linked list.
  137. ------------------------------------------------------------------------*/
  138. Dwarf_Unsigned 
  139. dwarf_add_directory_decl(
  140.     Dwarf_P_Debug dbg,
  141.     char *name,
  142.     Dwarf_Error *error)
  143. {
  144.     if (dbg->de_inc_dirs == NULL) {
  145.         dbg->de_inc_dirs = (Dwarf_P_Inc_Dir) 
  146.         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
  147.         if (dbg->de_inc_dirs == NULL) {
  148.         DWARF_P_DBG_ERROR(dbg,DW_DLE_INCDIR_ALLOC,DW_DLV_NOCOUNT);
  149.         }
  150.         dbg->de_last_inc_dir = dbg->de_inc_dirs;
  151.         dbg->de_n_inc_dirs = 1;
  152.     }
  153.     else {
  154.         dbg->de_last_inc_dir->did_next =  (Dwarf_P_Inc_Dir)
  155.         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
  156.         if (dbg->de_last_inc_dir->did_next == NULL) {
  157.         DWARF_P_DBG_ERROR(dbg,DW_DLE_INCDIR_ALLOC,DW_DLV_NOCOUNT);
  158.         }
  159.         dbg->de_last_inc_dir = dbg->de_last_inc_dir->did_next;
  160.         dbg->de_n_inc_dirs++;
  161.     }
  162.     dbg->de_last_inc_dir->did_name = (char *) _dwarf_p_get_alloc(dbg,strlen(name)+1);
  163.     if (dbg->de_last_inc_dir->did_name == NULL) {
  164.         DWARF_P_DBG_ERROR(dbg,DW_DLE_STRING_ALLOC,DW_DLV_NOCOUNT);
  165.     }
  166.     strcpy(dbg->de_last_inc_dir->did_name, name);
  167.     dbg->de_last_inc_dir->did_next = NULL;
  168.  
  169.     return dbg->de_n_inc_dirs;
  170. }
  171.  
  172. /*-----------------------------------------------------------------------
  173.     Add a file entry declaration to the debug_line section. Stored
  174.     in linked list. The data is immediately encodes as leb128
  175.     and stored in Dwarf_P_F_Entry_s struct.
  176. ------------------------------------------------------------------------*/
  177. Dwarf_Unsigned
  178. dwarf_add_file_decl(
  179.     Dwarf_P_Debug dbg,
  180.     char *name,
  181.     Dwarf_Unsigned dir_idx,
  182.     Dwarf_Unsigned time_mod,
  183.     Dwarf_Unsigned length,
  184.     Dwarf_Error *error)
  185. {
  186.     Dwarf_P_F_Entry cur;
  187.     char *data_idx, *data_time, *data_len;
  188.     char *ptr;
  189.     int nbytes_idx, nbytes_time, nbytes_len;
  190.  
  191.     if (dbg->de_file_entries == NULL) {
  192.         dbg->de_file_entries = 
  193.         (Dwarf_P_F_Entry) 
  194.             _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
  195.         if (dbg->de_file_entries == NULL) {
  196.         DWARF_P_DBG_ERROR(dbg,DW_DLE_FILE_ENTRY_ALLOC,DW_DLV_NOCOUNT);
  197.         }
  198.         cur = dbg->de_file_entries;
  199.         dbg->de_last_file_entry = cur;
  200.         dbg->de_n_file_entries = 1;
  201.     }
  202.     else {
  203.         cur = dbg->de_last_file_entry;
  204.         cur->dfe_next = 
  205.         (Dwarf_P_F_Entry) 
  206.             _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
  207.         if (cur->dfe_next == NULL) {
  208.         DWARF_P_DBG_ERROR(dbg,DW_DLE_FILE_ENTRY_ALLOC,DW_DLV_NOCOUNT);
  209.         }
  210.         cur = cur->dfe_next;
  211.         dbg->de_last_file_entry = cur;
  212.         dbg->de_n_file_entries++;
  213.     }
  214.     cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name)+1);
  215.     if (cur->dfe_name == NULL) {
  216.         DWARF_P_DBG_ERROR(dbg,DW_DLE_ALLOC_FAIL,DW_DLV_NOCOUNT);
  217.     }
  218.     strcpy((char *) cur->dfe_name, name);
  219.     data_idx = _dwarf_pro_encode_leb128(dir_idx, &nbytes_idx);
  220.     data_time = _dwarf_pro_encode_leb128(time_mod, &nbytes_time);
  221.     data_len = _dwarf_pro_encode_leb128(length, &nbytes_len);
  222.     cur->dfe_args = (char *)
  223.         _dwarf_p_get_alloc(dbg, nbytes_idx+nbytes_time+nbytes_len);
  224.     if (cur->dfe_args == NULL) {
  225.         DWARF_P_DBG_ERROR(dbg,DW_DLE_ALLOC_FAIL,DW_DLV_NOCOUNT);
  226.     }
  227.     ptr = cur->dfe_args;
  228.     memcpy((void *)ptr,data_idx,nbytes_idx);
  229.     ptr += nbytes_idx;
  230.     memcpy((void *)ptr,data_time,nbytes_time);
  231.     ptr += nbytes_time;
  232.     memcpy((void *)ptr,data_len, nbytes_len);
  233.     ptr += nbytes_len;
  234.     cur->dfe_nbytes = nbytes_idx+nbytes_time+nbytes_len;
  235.     cur->dfe_next = NULL;
  236.  
  237.     /* has be freed sometime 
  238.         free(data_idx);
  239.         free(data_time);
  240.         free(data_len);
  241.     */
  242.  
  243.     return dbg->de_n_file_entries;
  244. }
  245.     
  246.  
  247. /*---------------------------------------------------------------------
  248.     Initialize a row of the matrix for line numbers, meaning 
  249.     initialize the struct corresponding to it
  250. ----------------------------------------------------------------------*/
  251. void
  252. _dwarf_pro_reg_init(Dwarf_P_Line cur_line)
  253. {
  254.     cur_line->dpl_address = 0;
  255.     cur_line->dpl_file = 1;
  256.     cur_line->dpl_line = 1;
  257.     cur_line->dpl_column = 0;
  258.     cur_line->dpl_is_stmt = DEFAULT_IS_STMT;
  259.     cur_line->dpl_basic_block = false;
  260.     cur_line->dpl_next = NULL;
  261. }
  262.